<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>People Detail</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet">
    <style>
        body, html { background: #18181a !important; color: #fff; overflow-x: hidden; }
        .people-bg {
            position: relative;
            width: 100vw;
            height: 100vh;
            background: #222;
            overflow: hidden;
        }
        .people-bg-img {
            position: absolute; right: 0; top: 0; width: 50vw; min-width: 420px; height: 100vh; object-fit: cover; filter: brightness(0.98);
        }
        .people-bg-gradient {
            position: absolute; left: 0; top: 0; width: 100vw; height: 100%;
            background:
                linear-gradient(90deg, #18181a 0%, #18181a 55%, #18181a88 75%, #18181a00 100%),
                linear-gradient(180deg, #18181a00 80%, #18181a 100%);
            z-index: 1;
        }
        .people-main-info {
            position: relative; z-index: 2; display: flex; flex-direction: column; justify-content: center; height: 100vh; padding-left: 80px; max-width: 50vw;
        }
        .people-title {
            font-size: 2.6em; font-weight: bold; letter-spacing: 0.01em; margin-bottom: 10px;
            max-width: 65vw;
            word-break: break-word;
            margin-right: 32px;
        }
        .people-meta { color: #eee; font-size: 1.1em; margin-bottom: 10px; }
        .people-desc {
            color: #ccc; font-size: 1.08em; max-width: 700px; margin-bottom: 18px;
            display: -webkit-box;
            -webkit-line-clamp: 4;
            -webkit-box-orient: vertical;
            overflow: hidden;
            position: relative;
            transition: max-height 0.2s;
        }
        .people-desc.expanded {
            -webkit-line-clamp: unset;
            max-height: none;
            overflow: visible;
        }
        #descMoreBtnWrap {
            margin-top: 2px;
            margin-bottom: 10px;
            display: none;
        }
        #descMoreBtn {
            background: none;
            border: none;
            color: #4ea3ff;
            font-size: 1em;
            cursor: pointer;
            margin-top: 4px;
            margin-left: 0;
            padding: 0;
            display: none;
        }
        .people-section { margin: 0 auto; max-width: 1400px; padding: 0 40px; }
        .people-actions { display: flex; gap: 16px; margin-bottom: 8px; }
        .people-action-btn { background: #222; border: none; border-radius: 12px; padding: 10px 16px; color: #fff; font-size: 1.2em; display: flex; align-items: center; gap: 8px; transition: background 0.2s; }
        .people-action-btn img { width: 28px; height: 28px; border-radius: 6px; }
        .people-action-btn:hover { background: #444; }
        .people-action-label { font-size: 0.98em; color: #ccc; margin-top: 2px; }
        .relationships-title { color: #fff; font-size: 1.1em; font-weight: bold; margin: 32px 0 12px 0; }
        .relationships-list {
            display: flex; gap: 18px; overflow-x: auto; padding-bottom: 8px; margin-bottom: 18px;
            scrollbar-width: thin; scrollbar-color: #444 #222;
        }
        .relationships-list::-webkit-scrollbar {
            height: 8px; background: #222; border-radius: 6px;
        }
        .relationships-list::-webkit-scrollbar-thumb {
            background: #444; border-radius: 6px;
        }
        .relationships-list::-webkit-scrollbar-thumb:hover {
            background: #666;
        }
        .relationship-item { text-align: center; width: 110px; }
        .relationship-img { width: 80px; height: 80px; border-radius: 50%; object-fit: cover; margin-bottom: 8px; border: 2px solid #333; }
        .relationship-name { color: #fff; font-size: 1em; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .relationship-role { color: #aaa; font-size: 0.95em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .filmography-title { color: #fff; font-size: 1.1em; font-weight: bold; margin: 32px 0 12px 0; }
        .filmography-year { color: #fff; font-size: 1em; font-weight: bold; margin: 18px 0 8px 0; }
        .filmography-list {
            display: flex; flex-direction: row; flex-wrap: nowrap; gap: 18px; overflow-x: auto; padding-bottom: 8px; margin-bottom: 18px;
            scrollbar-width: thin; scrollbar-color: #444 #222;
        }
        .filmography-list::-webkit-scrollbar {
            height: 8px; background: #222; border-radius: 6px;
        }
        .filmography-list::-webkit-scrollbar-thumb {
            background: #444; border-radius: 6px;
        }
        .filmography-list::-webkit-scrollbar-thumb:hover {
            background: #666;
        }
        /* 统一卡片宽度为300px，高度400px，圆角10px，与movie-detail.html一致 */
        .filmography-list .morelike-item {
            width: 300px; min-width: 300px; background: #222; border-radius: 10px; overflow: hidden; cursor: pointer; transition: transform 0.18s;
        }
        .filmography-list .morelike-item img {
            width: 100%; height: 400px; object-fit: cover;
        }
        .filmography-list .morelike-title {
            color: #fff; font-size: 0.98em; font-weight: 500; padding: 8px 8px 6px 8px; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
        }
        @media (max-width: 900px) {
            .people-main-info { padding-left: 24px; }
            .people-section { padding: 0 10px; }
        }
    </style>
</head>
<body>
    <div class="people-bg">
        <div class="people-bg-gradient"></div>
        <img class="people-bg-img" id="peopleBgImg" src="" alt="">
        <div class="people-main-info">
            <div class="people-title" id="peopleTitle">People Name</div>
            <div class="people-meta" id="peopleMeta"></div>
            <div class="people-desc" id="peopleDesc"></div>
            <div id="descMoreBtnWrap"><span id="descMoreBtn" style="color:#4ea3ff;cursor:pointer;">more</span></div>
            <div class="people-actions" id="peopleActions"></div>
        </div>
    </div>
    <div class="people-section">
        <div class="relationships-title">Relationships</div>
        <div class="relationships-list" id="relationshipsList"></div>
        <div class="filmography-title">Filmography</div>
        <div id="filmographyContainer"></div>
    </div>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script>
    // ========== 工具 ==========
    function getQueryParam(name) {
        const url = window.location.search;
        const params = new URLSearchParams(url);
        return params.get(name);
    }
    function buildApiUrl(token, value) {
        return `https://saas.zeasn.tv/sp/api/device/v1/column/resourceDetail?token=${encodeURIComponent(token)}&resourceType=18&value=${encodeURIComponent(value)}&needPoster=true&posterWidth=1280&needAward=true`;
    }
    // ========== 数据加载 ==========
    async function loadPeopleDetail() {
        const token = getQueryParam('token');
        const value = getQueryParam('value');
        if (!token || !value) {
            $('#peopleTitle').text('参数缺失，无法加载人物详情');
            return;
        }
        const API_URL = buildApiUrl(token, value);
        try {
            const res = await fetch(API_URL);
            const data = await res.json();
            if (!data.data) {
                $('#peopleTitle').text('未获取到人物详情');
                return;
            }
            const d = data.data;
            // 顶部大图
            const poster = d.photo || (d.posters && d.posters[0] && d.posters[0].url) || (d.covers && d.covers[0] && d.covers[0].url) || '';
            $('#peopleBgImg').attr('src', poster);
            // 标题
            $('#peopleTitle').text(d.name || '');
            // meta
            let metaArr = [];
            if (Array.isArray(d.roles) && d.roles.length > 0) metaArr.push(d.roles.join(' / '));
            if (d.birthDate) metaArr.push(`${d.birthDate}${d.age ? ` (${d.age} years old)` : ''}`);
            if (d.birthPlace) metaArr.push(d.birthPlace);
            if (d.originLangs && d.originLangs.length > 0) metaArr.push(d.originLangs.join(', '));
            $('#peopleMeta').html(metaArr.join(' • '));
            // 简介
            let descText = d.description || '';
            function handleDescCollapse() {
                const $desc = $('#peopleDesc');
                const $btnWrap = $('#descMoreBtnWrap');
                const $btn = $('#descMoreBtn');
                $desc.data('full', descText);
                function update(expanded) {
                    $desc.toggleClass('expanded', expanded);
                    $btn.text(expanded ? 'less' : 'more');
                }
                // 先展开测真实行数
                $desc.text(descText);
                $desc.addClass('expanded');
                $btnWrap.hide();
                $btn.hide();
                setTimeout(() => {
                    // 获取真实高度和单行高度
                    const realHeight = $desc[0].scrollHeight;
                    $desc.removeClass('expanded');
                    // 现在是省略状态，测省略高度
                    const clampHeight = $desc[0].clientHeight;
                    // 重新展开测单行高度
                    $desc.addClass('expanded');
                    $desc[0].style.webkitLineClamp = 'unset';
                    const lineHeight = parseFloat(window.getComputedStyle($desc[0]).lineHeight);
                    const lines = Math.round(realHeight / lineHeight);
                    $desc.removeClass('expanded');
                    $desc[0].style.webkitLineClamp = '';
                    update(false);
                    if (lines > 4) {
                        $btnWrap.show();
                        $btn.show();
                        $btn.off('click').on('click', function() {
                            update(!$desc.hasClass('expanded'));
                        });
                    } else {
                        $btnWrap.hide();
                        $btn.hide();
                    }
                }, 100);
            }
            handleDescCollapse();
            // 人物操作按钮（如关注、点赞、评论等）
            $('#peopleActions').empty();
            // Relationships
            $('#relationshipsList').empty();
            if (Array.isArray(d.relationships) && d.relationships.length > 0) {
                d.relationships.forEach(item => {
                    $('#relationshipsList').append(`
                        <div class='relationship-item'>
                            <img class='relationship-img' src='${item.photo||''}' alt='${item.name||''}'>
                            <div class='relationship-name'>${item.name||''}</div>
                            <div class='relationship-role'>${item.role||''}</div>
                        </div>
                    `);
                });
            }
            // Filmography（通过新接口获取）
            // 恢复按年份分组，每组一行横向滚动
            $('#filmographyContainer').empty();
            if (d.id) {
                await loadFilmographyByActorDetail(token, d.id);
            }
        } catch (e) {
            $('#peopleTitle').text('加载失败');
        }
    }
    // 新增：通过actor/detail接口获取作品集
    async function loadFilmographyByActorDetail(token, contrId) {
        if (!token || !contrId) return;
        const url = `https://saas.zeasn.tv/whaletime/api/whalemeta/v1/actor/detail?imgWidth=&imgHeight=&contrId=${encodeURIComponent(contrId)}&token=${encodeURIComponent(token)}&moreInfo=true`;
        try {
            const res = await fetch(url);
            const data = await res.json();
            if (!data.data || !data.data.releaseYearMap) return;
            const releaseYearMap = data.data.releaseYearMap;
            // 恢复按年份分组，每组一行横向滚动
            Object.keys(releaseYearMap).sort((a,b)=>b-a).forEach(year => {
                $('#filmographyContainer').append(`<div class='filmography-year'>${year}</div>`);
                const $list = $(`<div class='filmography-list'></div>`);
                releaseYearMap[year].forEach(item => {
                    // 优先用 moreInfo 字段
                    const moreInfo = item.moreInfo || {};
                    const img = item.image || moreInfo.image || item.icon || item.poster || '';
                    const title = moreInfo.title || item.title || item.name || '';
                    // 分类
                    let categoriesArr = moreInfo.categories || item.categories || [];
                    let categoriesStr = '';
                    if (Array.isArray(categoriesArr) && categoriesArr.length > 0) {
                        categoriesStr = `<div style='color:#ffb84d;font-size:0.97em;padding:0 12px 2px 12px;'>${categoriesArr.map(c => c.name || c).join(' / ')}</div>`;
                    }
                    // 评分
                    let videoScoresStr = '';
                    if (moreInfo.videoScores && Array.isArray(moreInfo.videoScores) && moreInfo.videoScores.length > 0) {
                        videoScoresStr = `<div style='color:#ffd580;font-size:0.97em;padding:0 12px 2px 12px;'>${moreInfo.videoScores.map(vs => `${vs.type||vs.name||''}: ${vs.value||vs.score||''}`).join(' / ')}</div>`;
                    } else if (item.videoScores && Array.isArray(item.videoScores) && item.videoScores.length > 0) {
                        videoScoresStr = `<div style='color:#ffd580;font-size:0.97em;padding:0 12px 2px 12px;'>${item.videoScores.map(vs => `${vs.type||vs.name||''}: ${vs.value||vs.score||''}`).join(' / ')}</div>`;
                    } else if (item.score) {
                        videoScoresStr = `<div style='color:#ffd580;font-size:0.97em;padding:0 12px 2px 12px;'>${item.score}</div>`;
                    }
                    // seasonNumber / episodeCount
                    let seasonNumber = moreInfo.seasonNumber || item.seasonNumber;
                    let episodeCount = moreInfo.episodeCount || item.episodeCount;
                    if (item.value) {
                        try {
                            const v = typeof item.value === 'object' ? item.value : JSON.parse(item.value);
                            if (v.seasonNumber !== undefined) seasonNumber = v.seasonNumber;
                            if (v.episodeCount !== undefined) episodeCount = v.episodeCount;
                        } catch(e){}
                    }
                    let isSeasonType = (item.objectType === 'SEASON' || (item.value && typeof item.value === 'object' && item.value.objectType === 'SEASON'));
                    let seasonInfoStr = '';
                    if (isSeasonType && (seasonNumber || episodeCount)) {
                        let arr = [];
                        if (seasonNumber) arr.push('S' + seasonNumber);
                        if (episodeCount) arr.push(episodeCount + ' episodes');
                        seasonInfoStr = `<div style='color:#ffd580;font-size:0.97em;padding:0 12px 2px 12px;'>${arr.join(' / ')}</div>`;
                    }
                    // 时长
                    let duration = moreInfo.duration || item.duration;
                    if (item.value) {
                        try {
                            const v = typeof item.value === 'object' ? item.value : JSON.parse(item.value);
                            if (v.duration !== undefined) duration = v.duration;
                        } catch(e){}
                    }
                    function formatDuration(d) {
                        d = Number(d);
                        if (isNaN(d) || d <= 0) return '';
                        const h = Math.floor(d / 3600);
                        const m = Math.floor((d % 3600) / 60);
                        const s = d % 60;
                        let arr = [];
                        if (h > 0) arr.push(h + 'h');
                        if (m > 0) arr.push(m + 'm');
                        if (s > 0 || arr.length === 0) arr.push(s + 's');
                        return arr.join(' ');
                    }
                    let isMovieType = (
                        item.objectType === 'MOVIE' || item.objectType === 'VIDEO' || item.objectType === 'PROGRAM' ||
                        (item.value && typeof item.value === 'object' && ['MOVIE','VIDEO','PROGRAM'].includes(item.value.objectType))
                    );
                    let durationStr = '';
                    if (isMovieType && duration) {
                        durationStr = `<div style='color:#ffd580;font-size:0.97em;padding:0 12px 2px 12px;'>${formatDuration(duration)}</div>`;
                    }
                    // value 展示，统一为 {id, objectType} 格式
                    let valueObj = {id: item.id, objectType: item.objectType};
                    let valueStr = `<div style='color:#bbb;font-size:0.92em;word-break:break-all;padding:0 12px 2px 12px;'>${JSON.stringify(valueObj)}</div>`;
                    // deeplinkDetailList 展示
                    let deeplinkArr = moreInfo.deeplinkDetailList || item.deeplinkDetailList || [];
                    let deeplinkHtml = '';
                    if (Array.isArray(deeplinkArr) && deeplinkArr.length) {
                        deeplinkHtml = `<div style='display:flex;gap:10px;flex-wrap:wrap;padding:0 12px 8px 12px;'>` +
                            deeplinkArr.map(link =>
                                `<div style='display:flex;align-items:center;gap:4px;background:#181818;padding:2px 8px 2px 2px;border-radius:6px;'>`+
                                (link.sourceIcon ? `<img src='${link.sourceIcon}' style='width:22px;height:22px;border-radius:4px;'>` : '')+
                                `<span style='color:#fff;font-size:0.97em;'>${link.sourceName||''}</span>`+
                                `<span style='color:#aaa;font-size:0.85em;'>#${link.sourceId||''}</span>`+
                                `</div>`
                            ).join('') + `</div>`;
                    }
                    // 发布日期
                    let releaseTimeStr = '';
                    if (item.releaseTime) {
                        const d = new Date(Number(item.releaseTime));
                        if (!isNaN(d.getTime())) {
                            const y = d.getFullYear();
                            const m = (d.getMonth()+1).toString().padStart(2,'0');
                            const day = d.getDate().toString().padStart(2,'0');
                            releaseTimeStr = `<div style='color:#6cf;font-size:0.92em;padding:0 12px 2px 12px;'>${y}-${m}-${day}</div>`;
                        }
                    }
                    // 卡片结构与movie-detail.html morelike-item一致
                    const $card = $(`
                        <div class="morelike-item" tabindex="0">
                            <img src="${img}" alt="${title}">
                            <div class="morelike-title">${title}</div>
                            ${categoriesStr}${videoScoresStr}
                            <div style='text-align:left;'>${seasonInfoStr}${durationStr}${releaseTimeStr}${valueStr}${deeplinkHtml}</div>
                        </div>
                    `);
                    // 跳转逻辑
                    let valueParam = '';
                    if (item.value) {
                        valueParam = encodeURIComponent(typeof item.value === 'string' ? item.value : JSON.stringify(item.value));
                    } else {
                        valueParam = encodeURIComponent(JSON.stringify({id: item.id, objectType: item.objectType}));
                    }
                    const tokenParam = encodeURIComponent(token);
                    if (item.objectType === 'MOVIE') {
                        $card.css('cursor', 'pointer');
                        $card.on('click', function() {
                            window.open(`movie-detail.html?token=${tokenParam}&value=${valueParam}`, '_blank');
                        });
                    } else if (item.objectType === 'SEASON') {
                        $card.css('cursor', 'pointer');
                        $card.on('click', function() {
                            window.open(`season-detail.html?token=${tokenParam}&value=${valueParam}`, '_blank');
                        });
                    } else if (item.objectType === 'VIDEO') {
                        $card.css('cursor', 'pointer');
                        $card.on('click', function() {
                            window.open(`video-detail.html?token=${tokenParam}&value=${valueParam}`, '_blank');
                        });
                    } else if (item.objectType === 'PROGRAM') {
                        $card.css('cursor', 'pointer');
                        $card.on('click', function() {
                            window.open(`program-detail.html?token=${tokenParam}&value=${valueParam}`, '_blank');
                        });
                    }
                    $list.append($card);
                });
                $('#filmographyContainer').append($list);
            });
        } catch (e) {}
    }
    $(function(){
        loadPeopleDetail();
        // 鼠标滚轮横向滚动
        $('.relationships-list, .filmography-list').on('wheel', function(e) {
            if (e.originalEvent.deltaY === 0) return;
            this.scrollLeft += e.originalEvent.deltaY;
            e.preventDefault();
        });
    });
    </script>
</body>
</html> 